/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.action;

import info.xmlprint.run.Configuration;
import info.xmlprint.ui.message.GuiMessages;
import info.xmlprint.util.FileUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class CmdToPDF {

	private boolean stopRun = false;

	private Logger logger = Logger.getLogger(this.getClass().getName());

	private String tempDir;

	private String engineFile, foFile, pdfFile;

	final private boolean OS_IS_WIN = Configuration.isOs("windows");

	final private boolean OS_IS_LINUX = Configuration.isOs("linux");

	// final private boolean IS_MAC=Configuration.isOs("mac");

	public CmdToPDF() {
		init();
	}

	public void setPDFPath(String filePath) {
		pdfFile = filePath;
	}

	private void init() {
		tempDir = Configuration.getInstance().getXmlprintTmpDir();
		FileUtil.delAllFile(tempDir);

		engineFile = Configuration.getInstance().getEngineFilePath();
		foFile = Configuration.getInstance().getFoFilePath();
		pdfFile = Configuration.getInstance().getPdfFilePath();

		if (tempDir == null || engineFile == null || foFile == null
				|| pdfFile == null) {
			logger.error("tempDir: " + tempDir + " engineFile: " + engineFile
					+ " foFile: " + foFile + " pdfFile: " + pdfFile);
			stopRun = true;
		}
	}

	public boolean isStop() {
		return stopRun;
	}

	public void transform() {
		if (stopRun)
			return;

		if (!new File(foFile).isAbsolute()) {
			// System.out.println("no fo file");
			logger.error("no fo file");
			return;
		}

		ProgressMonitorDialog pd = new ProgressMonitorDialog(null);
		try {
			pd.run(true, true, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor)
						throws InvocationTargetException, InterruptedException {
					monitor.beginTask(GuiMessages.General_Gui_GetPDF,
							IProgressMonitor.UNKNOWN);
					foToPDF(monitor);
					monitor.done();
				}

			});
		} catch (InvocationTargetException e) {
			logger.error("", e);
			e.printStackTrace();
		} catch (InterruptedException e) {
			logger.error("", e);
			e.printStackTrace();
		}

	}

	private void foToPDF(IProgressMonitor monitor) {
		String[] cmd1;
		ProcessBuilder pb = new ProcessBuilder();
		/*
		 * Oracle recommends the usage of ProcessBuilder. However, this did not work here, so we stick to the old fashioned way
		 */
		if (OS_IS_WIN) {
			String monoFile = engineFile.substring(0, engineFile.lastIndexOf("/"));
			monoFile = monoFile.substring(0, monoFile.lastIndexOf("/")).concat(File.separator + "mono" + File.separator + "bin" + File.separator + "mono.exe ");
			
			//pb = new ProcessBuilder(monoFile, engineFile, " --fo ", foFile, "--pdf ", pdfFile);
			//pb.directory(new File(engineFile.substring(0,
								//engineFile.lastIndexOf("/"))));
			//logger.info("Command: " + pb);
			/*cmd1 = new String[] { "\""
					+ Configuration.getInstance().getEclipseRoot() + "print/"
					+ "Mono/bin/mono" + "\" " + "\"" + engineFile + "\""
					+ " --fo " + "\"" + foFile + "\"" + " --pdf " + "\""
					+ pdfFile + "\"" };*/
			cmd1 = new String[] { monoFile, engineFile, "--fo", foFile};		
		} else {
			cmd1 = new String[] { "mono", engineFile, "--fo", foFile };
		}
		logger.info("cmd1: " + cmd1);

		Runtime rt = Runtime.getRuntime();
		// pdf erzeugen
		Process pr1;
		//try {
			//pr1 = rt.exec(cmd1);
			//printProcess("*************\n\n" + cmd1 + "\n", pr1, monitor);
			//pr1.waitFor();
			/*
			 * TODO: This error handling as well as other info and error boxes
			 * should be in a separate class with appropriate routines.
			 */
			/*switch (pr1.exitValue()) {
			case 1:
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						MessageDialog.openError(Display.getDefault()
								.getActiveShell(),
								GuiMessages.Stileditor_Error_Error,
								GuiMessages.General_Error_one);
					}
				});
				break;
			case 2:
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						MessageDialog.openError(Display.getDefault()
								.getActiveShell(),
								GuiMessages.Stileditor_Error_Error,
								GuiMessages.General_Error_two);
					}
				});
				break;
			default: // case 0
				logger.info("XML-Print exists with: "+ pr1.exitValue());
			}
		} catch (IOException e) {
			logger.error("", e);
			e.printStackTrace();
		} catch (InterruptedException e) {
			logger.error("", e);
			e.printStackTrace();
		}*/

	}

	private void dialog() {

	}

	public void pdfDisplay() {
		if (stopRun)
			return;

		if (!new File(pdfFile).isAbsolute()) {
			logger.error("no pdf file");
			return;
		}

		String[] cmd2;
		if (OS_IS_WIN) {
			cmd2 = new String[] { "rundll32", "url.dll", "FileProtocolHandler",
					pdfFile };
		} else if (OS_IS_LINUX) {
			cmd2 = new String[] { "xdg-open", pdfFile };
		} else {
			/*
			 * MessageDialog.openError(null, "",
			 * "PDF Reader could not be found by xml-print, but " + pdfFile +
			 * " would be saved."); return;
			 */
			cmd2 = new String[] { "open", pdfFile };
		}
		Runtime rt = Runtime.getRuntime();

		Process pr2;
		try {
			pr2 = rt.exec(cmd2, null, new File(tempDir));
			pr2.waitFor();
		} catch (IOException e) {
			logger.error("", e);
			e.printStackTrace();
		} catch (InterruptedException e) {
			logger.error("", e);
			e.printStackTrace();
		}

	}

	// TODO
	public void saveToPDF(String str, String outfilePath) {

	}

	private void printProcess(String title, Process pr, IProgressMonitor monitor) {
		BufferedReader procout = new BufferedReader(new InputStreamReader(
				pr.getInputStream()));
		String line;
		try {
			while ((line = procout.readLine()) != null) {
				if (monitor != null) {
					monitor.setTaskName(line);
				}

				if (monitor.isCanceled()) {
					stopRun = true;
					return;
				}

				logger.info("" + line + "\n");
			}
		} catch (IOException e) {
			logger.error("", e);
			e.printStackTrace();
		}
	}

	public String getTempPath() {
		return tempDir;
	}

	public void setTempPath(String tempPath) {
		this.tempDir = tempPath;
	}

}
